/*jquery插件（拖动、滚动条）
 * @Author: kevin.huang
 * @Date: 2018-07-21 09:11:20 
 * @Last Modified by: kevin.huang
 */
/**下拉列表***/
function _createDropDownListFn($) {
    /***
     * jquery下拉列表
     * options = [
     * {
     *     text:'选项1',
     *     icon:'font-icon',
     *     click:function(){
     *          
     *     } 
     * },{
     * }]
     * ***/
    $.fn.dropDownList = function (options) {
        var $body = $(window.document.body).css("position", "relative");
        var dropDownWrap;
        var hideTimer;
        function makelist() {
            var ofs = this.offset();
            var curnId = this.data("_droplist_id");
            dropDownWrap = $body.children("#" + curnId);
            if (dropDownWrap.length === 0) {
                dropDownWrap = $("<div id='" + curnId + "' style='height:auto;position:absolute;z-index:2147483647;top:-10000px;display:none;' class='k_context_menu_container k_box_shadow k_box_radius'></div>");
                var it, $it;
                for (var i = 0, len = options.length; i < len; ++i) {
                    it = options[i];
                    $it = $('<div class="k_context_menu_item_cls"><span class="k_toolbar_img_black k_context_menu_item_ioc btn"><i class="fa ' + it.icon + '"></i></span><span class="k_context_menu_item_txt">' + it.text + '</span></div>');
                    $it.click(it.click).appendTo(dropDownWrap);
                }
                dropDownWrap.appendTo($body);
                dropDownWrap.on("mouseenter", function () {
                    clearTimeout(hideTimer);
                }).on("mouseleave", function () {
                    hidelist();
                });
            }
            var pos = { top: ofs.top + this.outerHeight(), left: ofs.left };
            dropDownWrap.css(pos).show();
        }
        function hidelist() {
            clearTimeout(hideTimer);
            hideTimer = setTimeout(function () {
                dropDownWrap.hide();
            }, 1000);
        }

        return this.each(function () {
            var $t = $(this);
            //console.log("display = " + $t.css("display"));
            var wrap = $("<div style='display: inline-block'></div>");
            wrap = $t.wrap(wrap).parent();
            var height = wrap.height();
            var color = $t.css("color");
            wrap.append("<i class='fa fa-down-dir' style='line-height:" + height + "px;color:" + color + ";font-size:1.2em;padding-left:5px;'></i>");
            var id = $B.getUUID();
            wrap.data("_droplist_id", id);
            wrap.css("cursor", "pointer").mouseenter(function () {
                makelist.call($(this));
            }).mouseleave(function () {
                hidelist.call($(this));
            });
        });
    };
}


/***提交服务器事件封装,集合request请求对当前提交按钮做防止二次提交处理****/
function _makeJquerySubmitEevent($) {
    $.fn.submit = function (event) {
        return this.each(function () {
            $(this).click(function () {
                var $t = $(this);
                if (!window["_submit_queues"]) {
                    window["_submit_queues"] = [];
                    setInterval(function () {
                        var newQ = [];
                        var now = new Date();
                        for (var i = 0, len = window["_submit_queues"].length; i < len; ++i) {
                            var q = window["_submit_queues"][i];
                            if ((now - q.date) < 2000) {//大于三秒则剔除
                                newQ.push(q);
                            } else {
                                q.btn = undefined;
                                q.date = undefined;
                            }
                        }
                        window["_submit_queues"] = newQ;
                    }, 3000);
                }
                window["_submit_queues"].push({
                    btn: $t,
                    date: new Date()
                });
                event.call($t);
            });
        });
    };
}

/****拖动实现****/
(function (global, factory) {
    if (typeof define === 'function' && define.amd && !window["_all_in_"]) {
        define(['jquery'], function ($) {
            return factory(global, $);
        });
    } else {
        factory(global, $);
    }
}(typeof window !== "undefined" ? window : this, function (window, $) {
    _createDropDownListFn($);
    _makeJquerySubmitEevent($);

    //实现jquery对象可拖动       
    var $doc = $(window.document);
    var $body;
    function _getBody() {
        if (!$body) {
            $body = $(window.document.body).css("position", "relative");
        }
        return $body;
    }  
    /*******鼠标提示插件**********/
    var tipEvents = {
        mouseenter: function (e,prs) {
            var $t = $(this);          
            var c = $t.attr("_tip");
            if (!c) {
                c = $t.data("_tip");
            }
            if(!c){
            	c = $t.text();
            }
            var opts = $t.data("tipopts");
            if (c) {
                clearTimeout(window["_clsTipTimer_"]);
                var top = 0, left = 0;
                var $b = _getBody();
                if (window.top !== window.self) {	/***在iframe嵌入页面窗口中*****/
                    var bof = $b.css("overflow");
                    if (bof === "visible") {/****查询父页面上的iframe容器滚动条*******/
                        var ifrid = $B.getIfrId();
                        var $ifr = $(parent.document.body).find("#" + ifrid);
                        var wrap = $ifr.parent();
                        if (wrap.hasClass("k_panel_content")) {
                            top = wrap.scrollTop();
                            left = wrap.scrollLeft();
                        }
                    } else {/****页面body已经声明了 滚动条****/
                        top = $doc.scrollTop();
                        left = $doc.scrollLeft();
                    }
                } else {
                    top = $doc.scrollTop();
                    left = $doc.scrollLeft();
                }
                var mPos ;
                if(e.isTrigger){
                	mPos = prs;
                }else{
                	mPos = { left: e.pageX, top: e.pageY };
                }
                mouseTip(mPos, c, $t.offset(), { top: top, left: left }, opts);
                if (window["_clsTipAct_"]) {
                    window["_clsTipAct_"].css("box-shadow", "none");
                }
                window["_clsTipAct_"] = $t.css("box-shadow", "0 0 2px 2px " + opts.activedColor);
            }
        },
        mouseleave: function () {
            if (window["$curTip_"]) {
                window["_clsTipTimer_"] = setTimeout(function () {
                    window["$curTip_"].hide();
                    window["$curTip_"] = undefined;
                    if (window["_clsTipAct_"]) {
                        window["_clsTipAct_"].css("box-shadow", "none");
                        window["_clsTipAct_"] = undefined;
                    }
                }, 650);
            }
        }
    };
    function mouseTip(pos, content, ofs, scroll, opts) {
        var html;
        if (typeof content === "string") {
            content = content.replace(/\r\n/g, "<br/>");
            if (content.indexOf("<br/>")) {
                content = content.split("<br/>");
            }
        }
        var fontSize = 14;
        if(opts.fontSize){
            fontSize = opts.fontSize;
        }
        var titleSize = fontSize * 1.2;
        var hasTitle = opts.title !== '';
        var padding = "padding:2px 10px;";
        if (hasTitle) {
            padding = "padding:2px 22px;";
        }
        if ($.isArray(content)) {
            html = [];
            for (var i = 0, len = content.length; i < len; ++i) {
                html.push("<p style='font-size:"+fontSize+"px;color:#fff;line-height: 1.3;" + padding + "'>" + content[i] + "</p>");
            }
            html = html.join("");
        } else {
            html = "<p style='font-size:"+fontSize+"px;color:#fff;line-height: 1.3;" + padding + "'>" + content + "</p>";
        }
        var $b = _getBody();
        var wrap = $b.children("#k_mouse_tip_wrap");
        var isShow = true;        
        if (wrap.length === 0) {
            wrap = $("<div style='font-size: "+fontSize+"px;line-height: 1.3;position:absolute;z-index: 2147483647; height: auto;' id='k_mouse_tip_wrap'><div class='k_box_shadow' style='border-radius: 4px;position:absolute;top:0;left:0;width:100%;height:100%;background:#303133;opacity:0.84'></div><div style='position:relative;padding: 6px 0px;' class='tip_content'></div></div>");
            isShow = false;
            wrap.on({
                mouseenter: function () {
                    clearTimeout(window["_clsTipTimer_"]);
                },
                mouseleave: tipEvents.mouseleave
            });
        } else {
            if (wrap.next().length > 0) {
                wrap.detach();
                isShow = false;
            }
        }
        var $cont = wrap.children(".tip_content");
        $cont.children().remove();
        $cont.html(html);
        if (hasTitle) {
        	$cont.prepend("<h6 style='border-bottom:1px dashed #CECECE ;font-size:"+titleSize+"px;text-align:left;padding-left:6px;color:#fff;font-weight: normal;'>" + opts.title + "</h6>");
        }
        var hidPos = { top: -10000, left: 0};
        if(opts.maxWidth){
        	pos["max-width"] = opts.maxWidth;
        	hidPos["max-width"] = opts.maxWidth;
        }
        if(opts.maxWidth){        	
        	pos["min-width"] = opts.minWidth;
        	hidPos["min-width"] = opts.minWidth;
        }
        if (isShow) {        	
            window["$curTip_"] = wrap.css(hidPos).show();
        } else {        	
            window["$curTip_"] = wrap.css(hidPos).appendTo($b);
        }
        var bh = $b.outerHeight();
        var bw = $b.outerWidth();
        var h = wrap.outerHeight();
        var w = wrap.outerWidth();
        var avh = bh - (pos.top - scroll.top);
        if (avh < h) {/**修正top***/
            pos.top = ofs.top - h;
            if (pos.top < 0) {
                pos.top = 0;
            }
        }
        var avw = bw - (pos.left - scroll.left);
        if (avw < w) {/**修正left***/
            pos.left = ofs.left - w;
            if (pos.left < 0) {
                pos.left = 0;
            }
        }              
        wrap.css(pos);
    }
    $.fn.mousetip = function (args) {
        var opts = $.extend({ title: '', activedColor: '#FFD334' }, args);
        this.each(function () {
        	var $t = $(this);
        	if(!$t.data("tipopts")){
        		$t.on(tipEvents).data("tipopts", opts);
        	}        	
        });
        return this;
    };
    /****以下为拖动jqueyr插件****/
    // try{
    //     // _moz_abspos
    //     document.designMode = "on";
    //     document.execCommand('enableObjectResizing', false, 'false');
    // }catch(ex){
    // } 
    var draggableDefaults = {
        nameSpace: 'draggable', //命名空间，一个对象可以绑定多种拖动实现
        which: undefined, //鼠标键码，是否左键,右键 才能触发拖动，默认左右键均可
        defaultZindex: 999999, //当z-index为auto时采用的层级数值
        holdTime: undefined, //按下鼠标多少毫秒才拖动，默认不设置立即可拖动
        isProxy: false, //是否产生一个空代理进行拖动
        updateProxy:true,//代理场景下是否更新目标元素
        disabled: false, //是否禁用拖动
        handler: undefined, //触发拖动的对象，默认是对象本身
        cursor: 'move', //鼠标样式
        axis: undefined, // v垂直方 h水平，默认全向           
        onDragReady: undefined, //鼠标按下时候准备拖动前，返回true则往下执行，返回false则停止
        onStartDrag: undefined, //开始拖动事件
        onDrag: undefined, //拖动中事件
        onStopDrag: undefined, //拖动结束事件
        onMouseUp: undefined, //当没有发生拖动，鼠标放开时候调用
        onProxyEnd:undefined, // function(args,pos) 代理拖动结束，返回false则不更新代理
        onCreateProxy:undefined	 // function(proxyObj,srcObj)，代理创建监听
    };

    /***
     * 根据鼠标计算位置
     * ****/
    function _compute(e) {
        var state = e.data,
            data = state._data,
            opts = state.options;
        //拖动后的 = 原先+拖动位移
        var leftOffset = e.pageX - data.startX,
            topOffset = e.pageY - data.startY;
        if (opts.axis === 'v') { //如果是垂直，则只改top
            leftOffset = 0;
        } else if (opts.axis === 'h') { //如果是水平拖动 则只改left
            topOffset = 0;
        }
        var left = data.startLeft + leftOffset,
            top = data.startTop + topOffset;
        data.leftOffset = leftOffset;
        data.topOffset = topOffset;
        data.oldLeft = data.left;
        data.oldTop = data.top;
        data.left = left;
        data.top = top;        
        var apply = true;
        if (state["onDragFn"]) {
            var args = {
                state: state,
                which: opts.which
            };
            var res = opts.onDrag(args);
            if (typeof res !== 'undefined') {
                apply = res;
            }
        }        
        data["apply"] = apply;
    }
    //移动事件 hasCallStartFn
    function _docMove(e) {
        //console.log("doc move............");
        var state = e.data;
        var opts = state.options;
        var data = state._data;
        data.pageX = e.pageX;
        data.pageY = e.pageY;
        /***** 是否已经调研了 onStartDrag *********/
        if (!state["hasCallStartFn"]) {
            //处理没有发生鼠标移动但是_docMove被触发的情况！！
            var leftOffset = e.pageX - data.startX,
                topOffset = e.pageY - data.startY;
            if (leftOffset === 0 && topOffset === 0) {
                console.log("过滤没有发生实际移动的 _docMove");
                return;
            }
            state["hasCallStartFn"] = true;
            state.target.data("_mvdata", data);
            if (state.callStartDragFn) {
                //提取拖动目标的zIndex 2147483647
                var zIndex = state.movingTarget.css("z-index");
                if (zIndex === "auto") {
                    zIndex = opts.defaultZindex;
                }
                state["zIndex"] = zIndex;
                state.movingTarget.css("z-index", 2147483647);
                try {
                    opts.onStartDrag({
                        state: state
                    });
                } catch (ex) {
                    if (console.error) {
                        console.error("onStartDrag error " + ex);
                    } else {
                        console.log("onStartDrag error " + ex);
                    }
                }
            }
        }
        _compute(e);
        if (data["apply"] && state.movingTarget) {
            var css = {
                cursor: state.options.cursor
            };
            if(opts.axis === 'v'){
                css.top = data.top + data.fixTop;
            }else if(opts.axis === 'h'){
                css.left = data.left + data.fixLeft;
            }else{
                css.top = data.top + data.fixTop;
                css.left = data.left + data.fixLeft;
            }           
            state.movingTarget.css(css);
        }
        if (typeof opts.notClearRange === "undefined") {
            //先清除document中的选择区域
            if (document.selection) {
                document.selection.empty();
            } else if (window.getSelection) {
                window.getSelection().removeAllRanges();
            }
        }
    }
    /***
     * 应该domcument监听鼠标放开事件
     * ***/
    function _docUp(e) {
        var state = e.data,
            data = state._data,
            opts = state.options,
            nameSpace = opts.nameSpace,
            target = state.target;
        data.pageX = e.pageX;
        data.pageY = e.pageY;
        $doc.off('.' + nameSpace);
        target.css('cursor', data.srcsor);
        if (opts.isProxy) { //代理移动方式,则需要更新目标位置           
            var css = {
                left: data.srcPos.left + data.leftOffset,
                top: data.srcPos.top + data.topOffset
            };
            var go = true;
            if(opts.onProxyEnd){
            	var ret = opts.onProxyEnd(state,css);
            	if(typeof ret !== "undefined"){
            		go = ret;
            	}
            }
            state["movingTarget"].remove();
            if(go && opts.updateProxy){
            	target.css(css);   
            }      
        }
        var onStopDrag = opts.onStopDrag;
        var returnVar;
        if (typeof onStopDrag === "function" && state["hasCallStartFn"]) {
            returnVar = onStopDrag({
                state: state
            });
        }
        state.target.removeData("_mvdata");
        if (state["hasCallStartFn"]) {
            var zIndex = state["zIndex"];
            state.movingTarget.css("z-index", zIndex);
        } else {
            if (opts.onMouseUp) {
                opts.onMouseUp({
                    state: state
                });
            }
        }
        data.leftOffset = 0;
        data.topOffset = 0;
        _getBody().css("cursor", "default");
        if (typeof returnVar !== "undefined") {
            return returnVar;
        }
    }
    //监听document鼠标按下事件
    function _docDown(e) {
        //console.log("_docDown............");
        var state = e.data,
            opts = state.options,
            data = state._data;
        var movingTarget = state.target;
        if (opts.isProxy) {
            var ofs = data.srcOfs,
                w = data.width,
                h = data.height,
            	fs = state.target.css("font-size"),
            	fcolor = state.target.css("color");
            var pp = state.target.css("padding");
            var clz = "";
            if(state.target.hasClass("k_box_size")){
            	clz = "k_box_size";
            }
            movingTarget = $("<div style='font-size:"+fs+";color:"+fcolor+";padding:"+pp+";cursor:" + opts.cursor + ";position:absolute;top:" + ofs.top + "px;left:" + ofs.left + "px' class='k_draggable_proxy "+clz+"'></div>");
            movingTarget.outerWidth(w).outerHeight(h);
            if(opts.onCreateProxy){
            	opts.onCreateProxy(movingTarget,state.target);
            }
            movingTarget.appendTo(_getBody());
        }
        if (typeof opts.onDrag === "function") {
            state["onDragFn"] = true;
        }
        state["movingTarget"] = movingTarget;
        _getBody().css("cursor", opts.cursor);
    }
    /***
     * 鼠标放开
     ****/
    function onMouseUp(e) {
        var dragtimer = $(this).data("dragtimer");
        if (dragtimer) {
            clearTimeout(dragtimer);
            var state = e.data;
            state.target.removeData("_mvdata");
            if (!state["hasCallStartFn"]) { //如果没有发生拖动
                var opts = state.options;
                if (opts.onMouseUp) {
                    opts.onMouseUp({
                        state: state
                    });
                }
            }
        }
    }
    /**
     * args应对编程trigger触发的鼠标事件
     * e参数中不存在pageX、pageY的情况
     * **/
    function onMouseDown(e, args) {
        if (args && !e["pageX"]) {
            e["pageX"] = args.pageX;
            e["pageY"] = args.pageY;
            e["which"] = args.which;
        }
        var state = e.data;
        var $t = state.target;
        var options = state.options;
        if (!options.which || options.which === e.which) {
            if (!options.disabled) {
                var go = true;
                if (typeof options.onDragReady === 'function') {
                    go = options.onDragReady.call($t, state);
                }
                if (go) {
                	var posParent = $t.parent();
                	var posAttr;
                	while(posParent.length > 0){
                		posAttr = posParent.css("position");
                		if(posAttr === "relative" || posAttr === "absolute"){
                			break;
                		}
                		posParent = posParent.parent();
                	}
                	var parentOfs =  posParent.offset();
                    var offset = $t.offset();
                    var position = $t.position();
                    //如果有css transform旋转，需要计算出 修正的偏移量    
                    var ofs = $B.getAnglePositionOffset($t);
                    var fixTop = ofs.fixTop;
                    var fixLeft = ofs.fixLeft;
                    var parent = $t.parent();
                    var scrollLeft = 0, scrollTop = 0;
                    if (parent[0] !== document.body) {
                        scrollLeft = parent.scrollLeft();
                        scrollTop = parent.scrollTop();
                    }
                    var srcsor = $t.css("cursor");
                    if (!srcsor) {
                        srcsor = 'default';
                    }
                    if (options.isProxy) {/***** 代理是放置于body下的，要用offset替换position *******/
	                    position = offset;
                    }else{
                        /**2019-05-21 补充 scroll量***/
                        var resetCss = {"position": "absolute"};
                        if(options.axis === 'v'){
                            resetCss.top = position.top + fixTop + scrollTop;
                        }else if(options.axis === 'h'){
                            resetCss.left = position.left + fixLeft + scrollLeft;
                        }else{
                            resetCss.top = position.top + fixTop + scrollTop;
                            resetCss.left = position.left + fixLeft + scrollLeft;
                        }   
                        $t.css(resetCss);
                        position = $t.position();
                    }                    
                    //封装拖动数据data对象，记录width,height,pageX,pageY,left 和top 等拖动信息
                    var data = {
                    	parentOfs:parentOfs,
                    	srcOfs:offset,
                    	srcPos:position,
                        startLeft: position.left + scrollLeft, //开始的位置信息	
                        startTop: position.top + scrollTop, //开始的位置信息	
                        scrollLeft: scrollLeft,
                        scrollTop: scrollTop,
                        left: position.left + scrollLeft, //当前left位置信息	
                        top: position.top + scrollTop, //当前top位置信息
                        oldLeft: undefined, //旧的left位置 
                        oldTop: undefined, //旧的top位置	
                        startX: e.pageX, //鼠标点击时的x坐标
                        startY: e.pageY, //鼠标点击时的y坐标
                        pageX:  e.pageX,
                        pageY:  e.pageY,
                        width: $t.outerWidth(),
                        height: $t.outerHeight(),
                        fixTop: fixTop,
                        fixLeft: fixLeft,
                        srcsor: srcsor, //原来的鼠标样式
                        leftOffset: 0, //鼠标left偏移
                        topOffset: 0 //鼠标top偏移
                    };
                    //console.log("1 "+JSON.stringify(data));
                    state["hasCallStartFn"] = false; //是否已经调用了onStartDrag   
                    state["_data"] = data;
                    state["parent"] = parent; //拖动对象的父dom
                    state["callStartDragFn"] = typeof options.onStartDrag === "function";
                    var nameSpace = options.nameSpace;
                    if (typeof options.holdTime !== 'undefined') {
                        var _this = $(this);
                        var timer = setTimeout(function () {
                            $t.css("cursor", state.options.cursor);
                            //往document上绑定鼠标移到监听 
                            _docDown({
                                data: state
                            });
                            $doc.on('mousemove.' + nameSpace, state, _docMove);
                            $doc.on('mouseup.' + nameSpace, state, _docUp);
                        }, options.holdTime);
                        _this.data("dragtimer", timer);
                    } else {
                        $t.css("cursor", state.options.cursor);
                        //往document上绑定鼠标监听 
                        $doc.on('mousedown.' + nameSpace, state, _docDown);
                        $doc.on('mousemove.' + nameSpace, state, _docMove);
                        $doc.on('mouseup.' + nameSpace, state, _docUp);
                    }
                }
            }
        }
    }
    /****
     * 构造函数
     * options：defaults参数
     * *****/
    $.fn.draggable = function (options) {
        var nameSpace = "draggable";
        if (typeof options === 'string') {
            if (arguments.length > 1) {
                nameSpace = arguments[1];
            }
            switch (options) {
                case 'enable': //启用拖动
                    return this.each(function () {
                        var $t = $(this);
                        var state = $t.data(nameSpace);
                        if (state) {
                            state.options.disabled = false;
                        }
                        $t.css("cursor", state.options.cursor);
                    });
                case 'disable': //禁用拖动
                    return this.each(function () {
                        var $t = $(this);
                        var state = $t.data(nameSpace);
                        if (state) {
                            state.options.disabled = true;
                        }
                        $t.css("cursor", "default");
                    });
                case 'unbind': //解除拖动
                    return this.each(function () {
                        var $t = $(this);
                        var state = $t.data(nameSpace);
                        state.handler.off('.' + nameSpace);
                        $t.removeData(nameSpace);
                        delete state.handler;
                        delete state.target;
                        delete state.options;
                        delete state.parent;
                    });
                default:
                    throw new Error("不支持:" + options);
            }
        }
        var opts = $.extend({}, draggableDefaults, options);
        if (opts.nameSpace) {
            nameSpace = opts.nameSpace; //默认的命名空间
        }
        return this.each(function () {
            var $t = $(this);
            var handler = $t; //handler是实际触发拖动的对象
            if (opts.handler) {
                handler = (typeof opts.handler === 'string' ? $t.find(opts.handler) : opts.handler);
                handler.css("cursor", options.cursor);
            }
            //存在则先解除已经绑定的拖动
            var state = $t.data(nameSpace);
            if (state) {
                state.handler.off('.' + nameSpace);
                delete state["handler"];
                delete state["target"];
                delete state["parent"];
                delete state["options"];
                delete state["_data"];
            }
            state = {
                handler: handler,
                target: $t,
                options: opts
            };
            $t.data(nameSpace, state);
            //注册事件 draggable 为命名空间
            handler.on('mousedown.' + nameSpace, state, onMouseDown);
            if (typeof opts.holdTime !== 'undefined') {
                handler.on('mouseup.' + nameSpace, state, onMouseUp);
            }
        });
    };
    $.fn.loading = function (message) {
        var loadingTip = $B.config.loading;
        if (message) {
            loadingTip = message;
        }
        var loadingHtml = "<div style='width:auto;z-index:2147483647;' class='k_datagrid_loading'><i class='fa fa-cog fa-spin fa-1.6x fa-fw margin-bottom'></i>" + loadingTip + "</div>";
        return this.each(function () {
            var $t = $(this);
            $t.html(loadingHtml);
        });
    };

    /****以下为jquey滚动条插件****   
     * 全局单列，鼠标hover上目标才显示scrollbar
     * @Author: kevin.huang 
     * @Date:  2019-01-06 12:00:01
     * Copyright (c): kevin.huang Released under MIT License
     * ****/
    var scrollDefaults = {
        slider: {
            "background-color": '#6F6F6F',
            "border-radius": "8px"
        },
        size: '6px',
        hightColor: "#05213B",
        bar: {
            "background-color": "#e4e4e4",
            "border-radius": "8px",
            "opacity": 0.5
        },
        setPadding: true,
        display: 'show',//显示方式，auto 自动显示，隐藏，show:固定显示
        wheelStep: 60,
        axis: 'xy', //x,y,xy
        checkItv: 0,//是否开启自动检查，0表示不开启，其他值 为毫秒数，表示checkItv毫秒检测一次内容是否发生变化并自动更正滚动条位置
        minHeight: 50,
        minWidth: 50
    };
    function scrollbar($el, opts) {
        this.opts = opts;
        this.yscroll = opts.yscroll;
        this.xscroll = opts.xscroll;
        this.$doc = $(document);
        this.jqObj = $el;
        this.$scrollWrap = this.jqObj.children(".k_scroll_wrap");
        this.scrollHeight = this.$scrollWrap[0].scrollHeight; //只有内容发生变化后，才会触发更新
        this.scrollWidth = this.$scrollWrap[0].scrollWidth; //只有内容发生变化后，才会触发更新
        if (this.yscroll) {
            this.$vbar = this.jqObj.children(".k_scroll_v_bar").css(this.opts.bar);
            this.$vbtn = this.$vbar.children("div").css(this.opts.slider);
            this._initVbtnHeight();
            this._initVbtnDragEvent();
            this._bindMousewheel();
            this._hightLine(this.$vbtn);
        }
        if (this.xscroll) {
            this.$Hbar = this.jqObj.children(".k_scroll_h_bar").css(this.opts.bar);
            this.$Hbtn = this.$Hbar.children("div").css(this.opts.slider);
            this._hightLine(this.$Hbtn);
            this._initHbtnWidth();
            this._initHbtnDragEvent();
        }
        this._bindContentScrollListner();
        var _this = this;
        if (this.opts.checkItv > 0 && (this.yscroll || this.xscroll)) {
            this.ivt = setInterval(function () {//每秒钟检查一次滚动内容高度、宽度是否发生了变化
                if (_this.jqObj.parent().length === 0) {
                    _this.destroy();
                } else {
                    _this.resetSliderPosition();
                }
            }, this.opts.checkItv);
        }
        this.showOrHideVbtn();
        this.showOrHideHbtn();
        if (this.opts.display === "auto" && (this.yscroll || this.xscroll)) {//开启自动隐藏功能
            this.fadeOut();
            this.jqObj.on({
                "mouseenter": function () {
                    _this.showOrHideVbtn();
                    _this.showOrHideHbtn();
                    _this.autoHide = false;
                },
                "mouseleave": function () {
                    if (!_this.scrolling) {
                        _this.fadeOut();
                    } else {
                        _this.autoHide = true;
                    }
                }
            });
        }
        $(window).resize(function () {
            _this.resetSliderPosByTimer();
        });
    }
    scrollbar.prototype = {
        _initHbtnWidth: function () {
            var scrollWidth = this.scrollWidth;
            var rate = this.$scrollWrap.width() / scrollWidth;
            var barWidth = this.$Hbar.width();
            var halft = barWidth / 2;
            var sliderWidth = rate * barWidth;
            if (sliderWidth < this.opts.minWidth) {
                sliderWidth = this.opts.minWidth;
            } else if (sliderWidth > halft) {
                sliderWidth = halft;
            }
            this.$Hbtn.css('width', sliderWidth);
        },
        _initHbtnDragEvent: function () {
            var _this = this;
            var slider = this.$Hbtn;
            var doc = this.$doc,
                dragStartPostion,
                dragStartScrollPostion,
                dragContBarRate;//滚动比例
            function moveHandler(e) {
                e.preventDefault();
                if (dragStartPostion == null) {
                    return;
                }
                if (!_this.$Hbtn.data("ishl")) {
                    _this.$Hbtn.css({ "background-color": _this.opts.hightColor }).data("ishl", true);
                    _this.$Hbar.css({ "opacity": 0.9 });
                }
                _this.scrollLeft(dragStartScrollPostion + (e.pageX - dragStartPostion) * dragContBarRate);
            }
            slider.on('mousedown', function (e) {
                e.preventDefault();
                dragStartPostion = e.pageX;
                dragStartScrollPostion = _this.$scrollWrap[0].scrollLeft;
                var scrollLen = _this.getMaxScrollLeftPosition();
                dragContBarRate = scrollLen / _this.getMaxHbtnPosition();
                _this.scrolling = true;
                doc.on('mousemove.kscroll', moveHandler).on('mouseup.kscroll', function () {
                    doc.off('.kscroll');
                    _this.maxScrollLeft = undefined;
                    _this.maxHbtnPosition = undefined;
                    _this.$Hbtn.css({ "background-color": _this.opts.slider["background-color"] }).removeData("ishl");
                    _this.$Hbar.css({ "opacity": _this.opts.bar["opacity"] });
                    _this.scrolling = false;
                    if (_this.autoHide) {
                        _this.fadeOut();
                    }
                });
            });
            slider.on('mouseup', function () {
                doc.off('mousemove.kscroll');
                doc.off('mouseup.kscroll');
            });
        },
        getMaxScrollLeftPosition: function () {
            if (typeof this.maxScrollLeft === "undefined") {
                var w = this.$scrollWrap.width();
                this.maxScrollLeft = Math.max(w, this.scrollWidth) - w;
            }
            return this.maxScrollLeft;
        },
        getMaxHbtnPosition: function () {
            if (typeof this.maxHbtnPosition === "undefined") {
                this.maxHbtnPosition = this.$Hbar.width() - this.$Hbtn.width();
            }
            return this.maxHbtnPosition;
        },
        getHbtnPosition: function () {
            var maxSliderPosition = this.getMaxHbtnPosition();
            return Math.min(maxSliderPosition, maxSliderPosition * this.$scrollWrap[0].scrollLeft / this.getMaxScrollLeftPosition());
        },
        showOrHideHbtn: function (scrollWidth) {
            if (this.xscroll) {
                if (!scrollWidth) {
                    scrollWidth = this.scrollWidth;
                }
                var width = this.$scrollWrap.width();
                if (scrollWidth <= width) {
                    this.$Hbar.hide();
                    this.jqObj.css("padding-bottom", 0);
                } else {
                    this.$Hbar.show();
                    this.jqObj.css("padding-bottom", this.$Hbar.height() + "px");
                }
            }
        },
        scrollLeft: function (v) {
            this.$scrollWrap.scrollLeft(v);
            //this.$scrollWrap.animate({scrollLeft:v},50);
        },
        /**y轴滚动条***/
        _initVbtnHeight: function () {
            var scrollHeight = this.scrollHeight;
            var barHeight = this.$vbar.height();
            var halft = barHeight / 2;
            var rate = this.$scrollWrap.height() / scrollHeight;
            var sliderHeight = rate * barHeight;
            if (sliderHeight < this.opts.minHeight) {
                sliderHeight = this.opts.minHeight;
            } else if (sliderHeight > halft) {
                sliderHeight = halft;
            }
            this.$vbtn.css('height', sliderHeight);
        },
        _initVbtnDragEvent: function () {
            var _this = this;
            var slider = this.$vbtn;
            var doc = this.$doc,
                dragStartPostion,
                dragStartScrollPostion,
                dragContBarRate;//滚动比例
            function moveHandler(e) {
                e.preventDefault();
                if (dragStartPostion == null) {
                    return;
                }
                if (!_this.$vbtn.data("ishl")) {
                    _this.$vbtn.css({ "background-color": _this.opts.hightColor }).data("ishl", true);
                    _this.$vbar.css({ "opacity": 0.9 });
                }
                _this.scrollTop(dragStartScrollPostion + (e.pageY - dragStartPostion) * dragContBarRate);
            }
            slider.on('mousedown', function (e) {
                e.preventDefault();
                dragStartPostion = e.pageY;
                dragStartScrollPostion = _this.$scrollWrap[0].scrollTop;
                var scrollLen = _this.getMaxScrollTopPosition();
                dragContBarRate = scrollLen / _this.getMaxVbtnPosition();
                _this.scrolling = true;
                doc.on('mousemove.kscroll', moveHandler).on('mouseup.kscroll', function () {
                    doc.off('.kscroll');
                    _this.maxScrollTop = undefined;
                    _this.maxVbtnPosition = undefined;
                    _this.$vbtn.css({ "background-color": _this.opts.slider["background-color"] }).removeData("ishl");
                    _this.$vbar.css({ "opacity": _this.opts.bar["opacity"] });
                    _this.scrolling = false;
                    if (_this.autoHide) {
                        _this.fadeOut();
                    }
                });
            });
            slider.on('mouseup', function () {
                doc.off('mousemove.kscroll');
                doc.off('mouseup.kscroll');
            });
        },
        getMaxScrollTopPosition: function () {
            if (typeof this.maxScrollTop === "undefined") {
                var h = this.$scrollWrap.height();
                this.maxScrollTop = Math.max(h, this.scrollHeight) - h;
            }
            return this.maxScrollTop;
        },
        getVbtnPosition: function () {
            var maxSliderPosition = this.getMaxVbtnPosition();
            return Math.min(maxSliderPosition, maxSliderPosition * this.$scrollWrap[0].scrollTop / this.getMaxScrollTopPosition());
        },
        getMaxVbtnPosition: function () {
            if (typeof this.maxVbtnPosition === "undefined") {
                this.maxVbtnPosition = this.$vbar.height() - this.$vbtn.height();
            }
            return this.maxVbtnPosition;
        },
        _bindMousewheel: function () {
            var _this = this;
            _this.$scrollWrap.on('mousewheel DOMMouseScroll', function (e) {
                e.preventDefault();
                var oEv = e.originalEvent,
                    wheelRange = oEv.wheelDelta ? - oEv.wheelDelta / 120 : (oEv.detail || 0) / 3;
                _this.scrollTop(_this.$scrollWrap[0].scrollTop + wheelRange * _this.opts.wheelStep);
                if (_this.$vbar.css("display") === "none") {
                    _this.showOrHideVbtn();
                    if (_this.xscroll) {
                        _this.showOrHideHbtn();
                    }
                }
            });
        },
        showOrHideVbtn: function (scrollHeight) {
            if (this.yscroll) {
                if (!scrollHeight) {
                    scrollHeight = this.scrollHeight;
                }
                var height = this.$scrollWrap.height();
                if (scrollHeight <= height) {
                    this.$vbar.hide();
                    this.jqObj.css("padding-right", 0);
                } else {
                    this.$vbar.show();
                    if (this.opts.display === "auto" && !this.opts.setPadding) {
                        this.jqObj.css("padding-right", 0);
                    } else {
                        this.jqObj.css("padding-right", this.$vbar.width() + "px");
                    }
                }
            }
        },
        scrollTop: function (v) {
            this.$scrollWrap.scrollTop(v);
            //this.$scrollWrap.animate({scrollTop:v},50);
        },
        resetSliderPosByTimer: function () {
            var _this = this;
            clearTimeout(this.sliderPosByTimer);
            this.sliderPosByTimer = setTimeout(function () {
                _this.resetSliderPosition();
            }, 500);
        },
        /*
        *当内容发生变化时候，重置位置,
        *检查 scrollHeight \scrollWidth 是否一致判断是否发生了变化
        ****/
        resetSliderPosition: function () {
            if (this.yscroll) {
                var scrollHeight = this.$scrollWrap[0].scrollHeight;
                this.scrollHeight = scrollHeight;
                this.maxScrollTop = undefined;
                this.maxVbtnPosition = undefined;
                if (typeof this.lastScrollHeight !== "undefined" && this.lastScrollHeight !== scrollHeight) {
                    if (this.$vbtn[0].style.top !== "0px") {
                        this.$vbtn[0].style.top = this.getVbtnPosition() + 'px';
                    }
                }
                this.lastScrollHeight = scrollHeight;
                //检查是否需要显示拖动条
                this.showOrHideVbtn(scrollHeight);
            }
            if (this.xscroll) {
                var scrollWidth = this.$scrollWrap[0].scrollWidth;
                this.scrollWidth = scrollWidth;
                this.maxScrollLeft = undefined;
                this.maxHbtnPosition = undefined;
                if (typeof this.lastScrollWidth !== "undefined" && this.lastScrollWidth !== scrollWidth) {
                    if (this.$Hbtn[0].style.left !== "0px") {
                        this.$Hbtn[0].style.left = this.getHbtnPosition() + 'px';
                    }
                }
                this.lastScrollWidth = scrollWidth;
                this.showOrHideHbtn(scrollWidth);
            }
        },
        _hightLine: function (btn) {
            var _this = this;
            btn.on({
                mouseenter: function () {
                    btn.css({ "background-color": _this.opts.hightColor }).data("ishl", true);
                    btn.parent().css({ "opacity": 0.9 });
                },
                mouseleave: function () {
                    btn.css({ "background-color": _this.opts.slider["background-color"] }).removeData("ishl");
                    btn.parent().css({ "opacity": _this.opts.bar["opacity"] });
                }
            });
        },
        _bindContentScrollListner: function () {
            var _this = this;
            _this.$scrollWrap.on('scroll', function () {
                if (_this.yscroll) {
                    _this.$vbtn[0].style.top = _this.getVbtnPosition() + 'px';
                }
                if (_this.xscroll) {
                    _this.$Hbtn[0].style.left = _this.getHbtnPosition() + 'px';
                }
            });
        },
        fadeOut: function () {
            if (this.yscroll) {
                this.$vbar.fadeOut();
            }
            if (this.xscroll) {
                this.$Hbar.fadeOut();
            }
        },
        destroy: function () {
            clearInterval(this.ivt);
            clearTimeout(this.sliderPosByTimer);
            for (var p in this) {
                if (this.hasOwnProperty(p)) {
                    delete this[p];
                }
            }
        }
    };
    /**jquery插件形式提供**/
    $.fn.myscrollbar = function (options, args) {
        var opts = $.extend({}, scrollDefaults, options);
        var mainWrap = $("<div style='width:100%;height:100%;position:relative;' class='k_scroll_main_wrap k_box_size'></div>");
        var scrollWrap = $("<div style='position:relative;width:100%;height:100%;overflow:hidden;' class='k_scroll_wrap k_box_size'></div>").appendTo(mainWrap);
        var parent = this.parent();
        this.detach().appendTo(scrollWrap);
        opts.yscroll = opts.axis === "xy" || opts.axis === "y";
        opts.xscroll = opts.axis === "xy" || opts.axis === "x";
        if (opts.yscroll) {
            mainWrap.css("padding-right", opts.size);
            if (opts.display === "auto" && !opts.setPadding) {
                mainWrap.css("padding-right", 0);
            }
            $("<div class='k_scroll_v_bar' style='overflow:hidden;position: absolute;top: 0;right: 0;width:" + opts.size + ";height: 100%;background-color: #e4e4e4;'><div style='cursor:pointer; position: absolute;top: 0;left: 0;width:" + opts.size + ";height: 30px;background-color: #525252;'></div></div>").appendTo(mainWrap);
        }
        if (opts.xscroll) {
            mainWrap.css("padding-bottom", opts.size);
            $("<div class='k_scroll_h_bar' style='overflow:hidden;position: absolute;left: 0;bottom: 0;width:100%;height:" + opts.size + ";background-color: #e4e4e4;'><div style='cursor:pointer; position: absolute;top: 0;left: 0;width:50px;height:" + opts.size + ";background-color: #525252;'></div></div>").appendTo(mainWrap);
        }
        parent.append(mainWrap);
        var ins = new scrollbar(mainWrap, opts);
        this.data("scrollIns", ins);
        return this;
    };
    $.fn.getMyScrollIns = function () {
        return this.data("scrollIns");
    };

    /***
     * 滑块控件 
     * @Author: kevin.huang 
     * @Date:  2019-02-06 22:26:01
     * Copyright (c): kevin.huang Released under MIT License
     * options = {
     *      width:'100%',
     *      height: 26,
     *      start: 0 ,
     *      end : 0 ,
     *      onChange:fn(val)     
     * }
     * ****/
    $.fn.myslider = function (options, args) {
        var opts;
        var isMethodCall = typeof options === "string";
        if (!isMethodCall) {
            opts = $.extend({}, {
                width: '100%',
                height: 16,
                start: 0,
                end: 100
            }, options);
            this.data("opts", opts);
        }
        this.each(function () {
            var $t = $(this);
            var maxLeft;
            var rate;
            if (isMethodCall) {
                if (options === "setValue" || options === "setValueSilent") {
                    var opt = $t.data("opts");
                    var itWrap = $t.children("div");
                    var mvbtn = itWrap.children("span");
                    if (!rate) {
                        maxLeft = itWrap.width() - mvbtn.width();
                        rate = maxLeft / (opt.end - opt.start);
                    }
                    var infPx = args * rate;
                    mvbtn.css("left", infPx);
                    if (opt.onChange && options !== "setValueSilent") {
                        opt.onChange(args, true);
                    }
                }
                return true;
            }
            var wrap = $("<div style='z-index:1; position:relative;border:1px solid #c5c5c5;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius: 3px;'></div>");
            wrap.css({
                width: opts.width,
                height: opts.height
            });
            var btn = $("<span tabindex='0' style='cursor:pointer;background:#fff;position:absolute;z-index:2; border:1px solid #c5c5c5;top:-4px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius: 3px;width:12px;height:" + (opts.height + 6) + "px'/>").appendTo(wrap);
            wrap.appendTo($t);
            btn.draggable({
                axis: 'h',
                onStartDrag: function (args) { //开始拖动                    
                    if (!rate) {
                        maxLeft = wrap.width() - btn.width();
                        rate = maxLeft / (opts.end - opts.start);
                    }
                },
                onDrag: function (args) { //拖动中
                    var state = args.state;
                    var data = state._data;
                    if (data.left < 0) {
                        data.left = 0;
                    } else if (data.left > maxLeft) {
                        data.left = maxLeft;
                    }
                    var val = parseInt(data.left / rate);
                    if (opts.onChange) {
                        opts.onChange(val);
                    }
                }
            }).keydown(function (e) {
                var which = e.which;
                var $t = $(this);
                var val;
                if (which === 39) {
                    val = $t.position().left + 1;
                    if (typeof maxLeft === "undefined") {
                        maxLeft = wrap.width() - btn.width();
                    }
                    if (val <= maxLeft) {
                        if (val < 0) {
                            val = 0;
                        }
                        if (val > maxLeft) {
                            val = maxLeft;
                        }
                        $t.css("left", val);
                    }
                } else if (which === 37) {
                    val = $t.position().left - 1;
                    if (val < 0) {
                        val = 0;
                    }
                    if (val >= 0) {
                        $t.css("left", val);
                    }
                }
                if (typeof val !== "undefined") {
                    if (!rate) {
                        rate = maxLeft / (opts.end - opts.start);
                    }
                    val = parseInt(val / rate);
                    if (val < opts.start) {
                        val = opts.start;
                    }
                    if (val > opts.end) {
                        val = opts.end;
                    }
                    if (opts.onChange) {
                        opts.onChange(val);
                    }
                }
            });
        });
    };
    return $;
}));